package com.gqz.equip.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gqz.equip.app.entity.EnStockPeriodTaskEntity;
import com.gqz.equip.app.entity.EnStockTaskEntity;
import com.gqz.equip.app.entity.EnStockTaskOperatePtEntity;
import com.gqz.equip.app.entity.po.MqStockPeriodTaskPo;
import com.gqz.equip.app.mapper.EnStockTaskMapper;
import com.gqz.equip.app.mapper.EnStockTaskOperateMapper;
import com.gqz.equip.app.mapstruct.EnStockTaskMapstruct;
import com.gqz.equip.app.service.IEnStockPeriodTaskService;
import com.gqz.equip.app.service.IEnStockTaskOperateService;
import com.gqz.equip.app.service.MqEnStockTaskService;
import com.gqz.equip.vo.EnStockTaskVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @ClassName MqEnStockTaskServiceImpl
 * @Description 能源-盘点任务
 */
@Service
@Slf4j
public class MqEnStockTaskServiceImpl extends ServiceImpl<EnStockTaskMapper, EnStockTaskEntity> implements MqEnStockTaskService {

    @Resource
    private EnStockTaskMapstruct mapstruct;

    @Resource
    private EnStockTaskOperateMapper taskOperateMapper;

    @Resource
    private IEnStockTaskOperateService operateService;

    @Resource
    private IEnStockPeriodTaskService periodTaskService;

    /**
     * 新增记录
     *
     * @param vos 记录数据
     * @return 影响的条数num
     */
    @Override
    @Transactional
    public int insert(List<EnStockTaskVo> vos) {
        List<EnStockTaskEntity> taskEntities = new ArrayList<>();
        List<EnStockPeriodTaskEntity> periodTaskEntities = new ArrayList<>();
        List<EnStockTaskOperatePtEntity> operateEntities = new ArrayList<>();
        vos.forEach(taskVo -> {
            Date nowDate = new Date();
            String taskNo = taskVo.getTaskNo();
            EnStockTaskEntity taskEntity = mapstruct.toEntity(taskVo);
            taskEntity.setId(taskNo);
            taskEntity.setCreateTime(nowDate);
            taskEntity.setTaskStatus("0");
            taskEntity.setTaskStatusName("未派单");
            taskEntity.setIsPeriod("0");

            EnStockTaskOperatePtEntity operateEntity = new EnStockTaskOperatePtEntity();
            operateEntity.setTaskNo(taskNo);
            operateEntity.setOptStatus("0");
            operateEntity.setOptStatusName("工单编制");
            operateEntity.setOptTime(nowDate);
            operateEntities.add(operateEntity);
            if ("1".equals(taskVo.getTaskTypeNo())) {
                // 周期性 需要向周期任务表插入数据
                EnStockPeriodTaskEntity periodTaskEntity = new EnStockPeriodTaskEntity();
                BeanUtil.copyProperties(taskVo, periodTaskEntity);
                periodTaskEntity.setId(taskNo);
                periodTaskEntity.setSourceTaskNo(taskNo);
                periodTaskEntity.setTaskStatus("0");
                periodTaskEntity.setTaskStatusName("未派单");
                periodTaskEntity.setExecutePeriodNum("2");
                periodTaskEntity.setExecuteStime(DateUtil.offsetDay(taskVo.getPlanStime(), Integer.parseInt(taskVo.getPeriod())));
                periodTaskEntity.setExecuteEtime(DateUtil.offsetDay(taskVo.getPlanEtime(), Integer.parseInt(taskVo.getPeriod())));
                periodTaskEntity.setCreateTime(nowDate);
                periodTaskEntities.add(periodTaskEntity);

                taskEntity.setTaskName(StrUtil.format("{}-周期内-{}", taskEntity.getTaskName(), "1"));
                taskEntity.setSourceTaskNo(taskNo);
            }
            taskEntities.add(taskEntity);
        });

        this.saveBatch(taskEntities);
        this.operateService.saveBatch(operateEntities);
        this.periodTaskService.saveBatch(periodTaskEntities);
        return taskEntities.size();
    }

    /**
     * 生成工单编号 年月日时分秒毫秒+4位随机数
     *
     * @return 编号
     */
    private String createTaskNo() {
        // 当前时间字符串-到毫秒
        String dateStr = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        // 随机数
        Random rand = new Random();
        String num4Str = String.format("%04d", rand.nextInt(1000));
        return dateStr + num4Str;
    }

    @Override
    @Transactional
    public int update(List<EnStockTaskVo> vos) {
        List<EnStockTaskEntity> taskEntities = new ArrayList<>();
        List<EnStockPeriodTaskEntity> periodTaskEntities = new ArrayList<>();
        List<EnStockTaskOperatePtEntity> operateEntities = new ArrayList<>();
        vos.forEach(taskVo -> {
            String taskNo = taskVo.getTaskNo();
            String taskStatus = taskVo.getTaskStatus();
            String appraiseStatus = taskVo.getAppraiseStatus();
            EnStockTaskEntity taskEntity = this.mapstruct.toEntity(taskVo);
            EnStockTaskOperatePtEntity operatePtEntity = new EnStockTaskOperatePtEntity();
            if ("99".equals(taskStatus) && "1".equals(appraiseStatus)) {
                // 归档操作并且合格，插入操作记录
                operatePtEntity.setTaskNo(taskNo);
                operatePtEntity.setOptTime(new Date());
                operatePtEntity.setOptStatus("99");
                operatePtEntity.setOptStatusName("归档");
                operateEntities.add(operatePtEntity);
            } else if ("99".equals(taskStatus) && "2".equals(appraiseStatus)) {
                // 归档操作但不合格，回退到环节
                operatePtEntity.setTaskNo(taskNo);
                operatePtEntity.setOptTime(new Date());
                operatePtEntity.setOptStatus("2");
                operatePtEntity.setOptStatusName("质量评价不合格");
                operateEntities.add(operatePtEntity);
                taskEntity.setTaskStatus("2");
                taskEntity.setTaskStatusName("已接单");
                taskEntity.setAppRunStatus("3");
            } else {
                EnStockPeriodTaskEntity periodTaskEntity = new EnStockPeriodTaskEntity();
                BeanUtil.copyProperties(taskVo, periodTaskEntity);
                if ("1".equals(taskVo.getTaskTypeNo())) {
                    periodTaskEntity.setExecuteStime(DateUtil.offsetDay(taskVo.getPlanStime(), Integer.parseInt(taskVo.getPeriod())));
                    periodTaskEntity.setExecuteEtime(DateUtil.offsetDay(taskVo.getPlanEtime(), Integer.parseInt(taskVo.getPeriod())));
                    periodTaskEntities.add(periodTaskEntity);
                }

            }
            taskEntities.add(taskEntity);
        });
        this.updateBatchById(taskEntities);
        this.operateService.saveBatch(operateEntities);
        this.periodTaskService.updateBatchById(periodTaskEntities);
        return 1;
    }

    /**
     * 派单
     *
     * @param vo vo
     * @return
     */
    @Override
    @Transactional
    public int sendOrder(EnStockTaskVo vo) {
        String taskNo = vo.getTaskNo();
        String id = vo.getId();
        if (StringUtils.isBlank(taskNo) && StringUtils.isBlank(id)) {
            ExceptionUtil.wrapRuntimeAndThrow("taskNo or id can not be empty");
        }
        EnStockTaskEntity taskEntity = mapstruct.toEntity(vo);
        taskEntity.setTaskStatus("1");
        taskEntity.setTaskStatusName("已派单");
        taskEntity.setRunStatus("1");
        taskEntity.setRunStatusName("待办");
        taskEntity.setAppRunStatus("1");


        LambdaQueryWrapper<EnStockTaskEntity> updateWrapper = new LambdaQueryWrapper();
        updateWrapper.eq(StringUtils.isNotBlank(taskEntity.getTaskNo()), EnStockTaskEntity::getTaskNo, taskEntity.getTaskNo());
        updateWrapper.or();
        updateWrapper.eq(StringUtils.isNotBlank(taskEntity.getId()), EnStockTaskEntity::getId, taskEntity.getId());
        updateWrapper.eq(EnStockTaskEntity::getIsDel, "0");
        this.baseMapper.update(taskEntity, updateWrapper);
        this.saveTaskOperate(vo, "1", "派单");
        return 1;
    }

    /**
     * 保存任务操作
     *
     * @param taskVo        taskVo
     * @param optStatus     optStatus
     * @param optStatusName optStatusName
     */
    private void saveTaskOperate(EnStockTaskVo taskVo, String optStatus, String optStatusName) {
        EnStockTaskOperatePtEntity operateEntity = new EnStockTaskOperatePtEntity();
        operateEntity.setTaskNo(taskVo.getTaskNo());
        operateEntity.setOptStatus(optStatus);
        operateEntity.setOptStatusName(optStatusName);
        operateEntity.setOptTime(new Date());

        taskOperateMapper.insert(operateEntity);
    }

    @Override
    @Transactional
    public void createStockPeriodTask(MqStockPeriodTaskPo po) {
        this.periodTaskService.updateBatchById(po.getUpdateEnStockPeriodTaskEntities());
        this.periodTaskService.saveBatch(po.getInsertEnStockPeriodTaskEntities());
        this.saveBatch(po.getInsertStockTaskEntities());
        this.updateBatchById(po.getUpdateStockTaskEntities());
        this.operateService.saveBatch(po.getInsertOperateEntities());
    }

}
